package routes

import (
	"gitee.com/konglinglong/car/backend/internal/auth"
	"gitee.com/konglinglong/car/backend/internal/handlers"
	"gitee.com/konglinglong/car/backend/internal/middleware"
	"github.com/gin-gonic/gin"
)

// SetupRoutes configures all application routes
func SetupRoutes(r *gin.Engine, jwtManager *auth.JWTManager, h *handlers.Handlers) {
	// Apply global middleware
	r.Use(middleware.CORS())
	r.Use(middleware.Logger())
	r.Use(middleware.Recovery())
	r.Use(middleware.RateLimitMiddleware())

	// Health check endpoint
	r.GET("/health", h.HealthCheck)

	// API v1 routes
	v1 := r.Group("/api/v1")
	{
		// Public routes (no authentication required)
		public := v1.Group("/")
		{
			public.POST("/auth/login", h.Login)
			public.POST("/auth/register", h.Register)
		}

		// Protected routes (authentication required)
		protected := v1.Group("/")
		protected.Use(middleware.AuthMiddleware(jwtManager))
		{
			// User management
			protected.GET("/user/profile", h.GetUserProfile)
			protected.PUT("/user/profile", h.UpdateUserProfile)
			protected.POST("/auth/refresh", h.RefreshToken)

			// Repository management
			protected.GET("/repositories", h.ListRepositories)
			protected.POST("/repositories", h.CreateRepository)
			protected.GET("/repositories/:name", h.GetRepository)
			protected.PUT("/repositories/:name", h.UpdateRepository)
			protected.DELETE("/repositories/:name", h.DeleteRepository)

			// Artifact management
			protected.GET("/repositories/:name/artifacts", h.ListArtifacts)
			protected.GET("/repositories/:name/artifacts/:digest", h.GetArtifact)
			protected.DELETE("/repositories/:name/artifacts/:digest", h.DeleteArtifact)

			// Tag management
			protected.GET("/repositories/:name/tags", h.ListTags)
			protected.POST("/repositories/:name/tags", h.CreateTag)
			protected.DELETE("/repositories/:name/tags/:tag", h.DeleteTag)
		}

		// Admin routes (admin role required)
		admin := v1.Group("/admin")
		admin.Use(middleware.AuthMiddleware(jwtManager))
		admin.Use(middleware.AdminMiddleware())
		{
			// User management (admin only)
			admin.GET("/users", h.ListUsers)
			admin.GET("/users/:id", h.GetUser)
			admin.PUT("/users/:id", h.UpdateUser)
			admin.DELETE("/users/:id", h.DeleteUser)

			// System management
			admin.GET("/stats", h.GetSystemStats)
			admin.GET("/audit-logs", h.GetAuditLogs)
		}
	}

	// Docker Registry API v2 routes
	registry := r.Group("/v2")
	{
		// Base API version check
		registry.GET("/", h.RegistryVersion)

		// Repository catalog
		registry.GET("/_catalog", h.RegistryCatalog)

		// Repository-specific routes
		repo := registry.Group("/:name")
		{
			// Tag listing
			repo.GET("/tags/list", h.RegistryListTags)

			// Manifest operations
			repo.GET("/manifests/:reference", h.RegistryGetManifest)
			repo.PUT("/manifests/:reference", h.RegistryPutManifest)
			repo.DELETE("/manifests/:reference", h.RegistryDeleteManifest)

			// Blob operations
			repo.GET("/blobs/:digest", h.RegistryGetBlob)
			repo.HEAD("/blobs/:digest", h.RegistryHeadBlob)
			repo.DELETE("/blobs/:digest", h.RegistryDeleteBlob)

			// Blob upload operations
			repo.POST("/blobs/uploads/", h.RegistryInitiateUpload)
			repo.GET("/blobs/uploads/:uuid", h.RegistryGetUploadStatus)
			repo.PATCH("/blobs/uploads/:uuid", h.RegistryUploadChunk)
			repo.PUT("/blobs/uploads/:uuid", h.RegistryCompleteUpload)
			repo.DELETE("/blobs/uploads/:uuid", h.RegistryCancelUpload)
		}
	}

	// App Container Image Discovery Protocol routes
	discovery := r.Group("/discovery")
	{
		// Discovery metadata endpoint
		discovery.GET("/", h.DiscoveryHandler)
		
		// App image listing
		discovery.GET("/images", h.ListAppImages)
	}
	
	// App image specific routes (separate group to avoid wildcard conflicts)
	appImages := r.Group("/discovery/app")
	{
		// App image metadata
		appImages.GET("/*name", h.GetAppImageMeta)
	}
	
	// App image details routes
	appDetails := r.Group("/discovery/app-details")
	{
		// App image details
		appDetails.GET("/*name", h.GetAppImageDetails)
	}
	
	// App image signature routes
	appSig := r.Group("/discovery/app-signature")
	{
		// App image signature
		appSig.GET("/*name", h.DiscoverySignature)
	}

	// Alternative discovery endpoints following ACI spec
	aci := r.Group("/aci")
	{
		// ACI discovery endpoint
		aci.GET("/", h.DiscoveryHandler)
	}
	
	// ACI image metadata routes
	aciImages := r.Group("/aci/images")
	{
		// ACI image metadata
		aciImages.GET("/*name", h.GetAppImageMeta)
	}
	
	// ACI signature routes
	aciSig := r.Group("/aci/signature")
	{
		// ACI signature
		aciSig.GET("/*name", h.DiscoverySignature)
	}

	// Artifacts API routes
	artifacts := r.Group("/api/v1/artifacts")
	{
		// Get supported artifact types
		artifacts.GET("/types", h.GetSupportedTypes)
		
		// Search artifacts across repositories
		artifacts.GET("/search", h.SearchArtifacts)
		
		// Repository-specific artifact routes
		repoArtifacts := artifacts.Group("/:repository")
		{
			// List artifacts in repository
			repoArtifacts.GET("/", h.ListArtifactsByRepository)
			
			// Upload artifact (requires authentication)
			repoArtifacts.POST("/upload", middleware.AuthMiddleware(jwtManager), h.UploadArtifact)
			
			// Artifact-specific routes
			artifactRoutes := repoArtifacts.Group("/:name")
			{
				// List all versions of an artifact
				artifactRoutes.GET("/versions", h.ListArtifactVersions)
				
				// Version-specific routes
				versionRoutes := artifactRoutes.Group("/:version")
				{
					// Get artifact metadata
					versionRoutes.GET("/metadata", h.GetArtifactMetadata)
					
					// Download artifact
					versionRoutes.GET("/download", h.DownloadArtifact)
					
					// Delete artifact (requires authentication)
					versionRoutes.DELETE("/", middleware.AuthMiddleware(jwtManager), h.DeleteArtifactByVersion)
				}
			}
		}
	}
}
